#!/usr/bin/python
#
#  This file poles the Occam network and grabs the info fields from each DSL port
#  The corresponding information is then put in (or updated) in the database
#
#  Created by:  Casey Trader
#
#  Copyright (c) 2010 Casey Trader
#
#  Permission is hereby granted, free of charge, to any person obtaining a copy
#  of this software and associated documentation files (the "Software"), to deal
#  in the Software without restriction, including without limitation the rights
#  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
#  copies of the Software, and to permit persons to whom the Software is
#  furnished to do so, subject to the following conditions:
#
#  The above copyright notice and this permission notice shall be included in
#  all copies or substantial portions of the Software.
#
#  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
#  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
#  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
#  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
#  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
#  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
#  THE SOFTWARE.


from time import gmtime, strftime, sleep
import re
import getpass
import sys
import telnetlib
import MySQLdb

try:
	conn = MySQLdb.connect( host = "localhost",
				user = "root",
				passwd = "M00nshine",
				db = "jala_db")
except MySQLdb.Error, e:
	print "Error %d: %s" % (e.args[0], e.args[1])
	sys.exit(1)
cursor = conn.cursor()

###  Function Definitions  ###
def parser(blade_ip, results):
	values = ""
	#  seperate the results into individual lines that we can parse over
	for line in results.rsplit("\r\n"):
		#  Check to see if the line has the port number
		if re.match("^interface dsl +", line):
			# split the line at each space
			tmp = re.split("(\s+)", line)
			port_num = tmp[4]
			#print port_num
			values = values+"\r\n"+blade_ip+"|"+port_num
			#values = "\r\n"+values+ line
		#  Check to see if the line has an "info" field
		elif re.match("^ info +", line):
			# remove "info" from the beginning of the line
			info = re.sub(" info ", "", line)
			values = values+"|"+info
			#print info

	for line in values.rsplit("\r\n"):
		#  Do nothing for empty lines
		if line != "":
			#  Split the line apart based on the delimiter "|"
			#  Need to escape the pipe ("|") character
			tmp = re.split("\|", line)
			blade_ip = tmp[0]
			interface_num = tmp[1]
			#  Declare all info fields as empty in case they don't all have values
			info_1 = ""
			info_2 = ""
			info_3 = ""
			#  See how long the array is (see how many info fields there are)
			array_len = len(tmp)
			if array_len > 2:
				#  We need to escape (or use the literal) value of the variable in the DB
				info_1 = tmp[2]
			if array_len > 3:
				info_2 = tmp[3]
			if array_len > 4:
				info_3 = tmp[4]
		
			print blade_ip+"/"+interface_num+"/"+info_1+"/"+info_2+"/"+info_3
			update_db(blade_ip, interface_num, info_1, info_2, info_3)
	#  DEBUG
	#print values

def update_db(blade_ip, port_num, info_1, info_2, info_3):
	info_1 = conn.escape_string(info_1)
	info_2 = conn.escape_string(info_2)
	info_3 = conn.escape_string(info_3)

	cursor.execute("SELECT * FROM port_info WHERE blade_ip = '"+blade_ip+"' AND port_num = '"+port_num+"'")
	if cursor.rowcount > 0:
	# If a row exists then update it
		cursor.execute("UPDATE port_info SET info_1 = '"+info_1+"', info_2 = '"+info_2+"', info_3 = '"+info_3+"' WHERE blade_ip = '"+blade_ip+"' AND port_num = '"+port_num+"'") 	
		print "Updated DB"
	else:
	# If a row dowsn't exist, then instert it
		cursor.execute("INSERT INTO port_info (blade_ip, port_num, info_1, info_2, info_3) VALUES ('"+blade_ip+"','"+port_num+"','"+info_1+"','"+info_2+"','"+info_3+"')") 	
		print "Inserted into DB"

###  END OF FUNCTION DEFINITIONS  ###

#  Grab all of the blades from database that we need to pole
start_time = strftime('%a, %d %b %Y %H:%M:%S', gmtime()) 
cursor.execute("SELECT * FROM devices WHERE device_type = '6252' OR device_type = '6252 02' OR device_type = '6252 03'")
#cursor.execute("SELECT * FROM devices WHERE device_ip = '172.16.3.80'")
rows = cursor.fetchall()
blade_total = cursor.rowcount
for row in rows:
	#  Slow the script down a little so that we don't have issues with slow telnet on blades
	sleep(1)
	blade_ip = row[2]
	print "Starting on: "+blade_ip
	priv_pass = "occam"
	enable_pass = "razor"

	tn = telnetlib.Telnet(blade_ip)
	# Use for debugging
	#tn.set_debuglevel(3)

	#  Perform login sequence
	tn.read_until("Password: ")
	tn.write(priv_pass + "\r")
	tn.write("terminal length 0\r")
	tn.write("enable\r")
	tn.read_until("Password: ", 1)
	tn.write(enable_pass + "\r")

	#tn.write("show run\r")
	#  Display each of the individual 48 ports
	for i in range(1, 49):
        	tn.write("show run interface dsl " + str(i) + "\r")
	#  Exit enable mode
	tn.write("exit\r")
	#  Exit priv mode
	tn.write("exit\r")

	#  Call the parser function with the results
	#print tn.read_all()
	results = tn.read_all()
	parser(blade_ip, results)
	#  Close the connection to this blade
	tn.close()

#  Close the DB connections when we are done polling everything
cursor.close()
conn.close()
end_time = strftime('%a, %d %b %Y %H:%M:%S', gmtime()) 

print "Blade Total: "+str(blade_total)
print "Start Time : "+start_time
print "END Time   : "+end_time

